import java.util.Random;

public class Test02 {
    public int findKthLargest(int[] nums, int k) {
        // 将 k 转换为零索引的数组下标（第 k 大的元素对应的索引）
        int targetIndex = nums.length - k;
        return quickselect(nums, 0, nums.length - 1, targetIndex);
    }

    private int quickselect(int[] nums, int left, int right, int targetIndex) {
        if (left == right) { // 如果数组中只有一个元素
            return nums[left];
        }

        // 在 left 和 right 之间随机选择一个 pivotIndex
        Random random = new Random();
        int pivotIndex = left + random.nextInt(right - left + 1);

        // 执行分区操作
        pivotIndex = partition(nums, left, right, pivotIndex);

        // 检查 pivotIndex 是否为目标索引
        if (pivotIndex == targetIndex) {
            return nums[pivotIndex]; // 找到目标元素
        } else if (pivotIndex < targetIndex) {
            // 继续在右侧部分查找
            return quickselect(nums, pivotIndex + 1, right, targetIndex);
        } else {
            // 继续在左侧部分查找
            return quickselect(nums, left, pivotIndex - 1, targetIndex);
        }
    }

    private int partition(int[] nums, int left, int right, int pivotIndex) {
        int pivot = nums[pivotIndex];
        // 将 pivot 移动到数组的末尾
        swap(nums, pivotIndex, right);
        int storeIndex = left;

        // 将所有小于 pivot 的元素移动到左侧
        for (int i = left; i < right; i++) {
            if (nums[i] < pivot) {
                swap(nums, storeIndex, i);
                storeIndex++;
            }
        }

        // 将 pivot 移动到它的最终位置
        swap(nums, storeIndex, right);
        return storeIndex;
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
